package demo.designPattern.aop;

/**
 * <h1>AOP(aspect object programming)面向切面编程</h1> 我们可以从以下几个层面来实现AOP：
 * <li>在编译期修改源代码
 * <li>在运行期字节码加载前修改字节码
 * <li>在运行期字节码加载后动态创建代理类的字节码
 * <p>
 * <h2>AOP各种实现机制的比较:</h2>
 * <li>静态AOP。机制: 静态织入。原理：在编译期，切面直接以字节码的形式编译到目标字节码文件中。优点： 对系统无性能影响。缺点： 灵活性不够
 * <li>动态AOP。机制: 动态代理 。原理： 在运行期，目标类加载后，为接口动态生成代理类，将切面织入到代理类中 。优点： 相对于静态AOP更加灵活 。缺点：切入的关注点需要实现接口，对系统有一点性能影响
 * <li>动态字节码生成。机制: CGLIB。原理： 在运行期，目标类加载后，动态构建字节码文件生成目标类的子类，将切面逻辑加入到子类中 。优点：没有接口也可以织入 。缺点： 扩展类的实例方法为final时，则无法进行织入
 * <li>自定义类加载器 。原理： 在运行期，目标加载前，将切面逻辑加到目标字节码里 。优点：可以对绝大部分类进行织入 。缺点：代码中如果使用了其他类加载器，则这些类将不会被织入
 * <li>字节码转换 。原理： 在运行期，所有类加载器加载字节码前进行拦截 。优点： 可以对所有类进行织入
 * <p>
 * 
 * 
 * <h2>AOP功能</h2>
 * <li>性能监控：在方法调用前后记录调用时间，方法执行太长或超时报警
 * <li>缓存代理：缓存某方法的返回值，下次执行该方法时，直接从缓存里获取
 * <li>软件破解：使用AOP修改软件的验证类的判断逻辑
 * <li>记录日志：在方法执行前后记录系统日志
 * <li>工作流系统：工作流系统需要将业务代码和流程引擎代码混合在一起执行，那么我们可以使用AOP将其分离，并动态挂接业务
 * <li>权限验证：方法执行前验证是否有权限执行当前方法，没有则抛出没有权限执行异常，由业务代码捕捉
 * 
 */
public interface AopInfo {

    /**
     * <h2>AOP</h2> 面向切面编程，采用横向抽取机制，取代了传统的纵向继承。是一种编程思想，旨在通过分离横切关注点，提高模块化，可以跨越对象关注点。
     * 
     * Aop的典型应用即spring的事务机制，日志记录。 利用AOP可以对业务逻辑的各个部分进行隔离，从而使得业务逻辑各部分之间的耦合度降低，提高程序的可重用性，同时提高了开发的效率。
     * 主要功能是：日志记录，性能统计，安全控制，事务处理，异常处理等等；
     * 主要的意图是：将日志记录，性能统计，安全控制，事务处理，异常处理等代码从业务逻辑代码中划分出来，通过对这些行为的分离，我们希望可以将它们独立到非指导业务逻辑的方法中，进而改变这些行为的时候不影响业务逻辑的代码。
     */
    void aop();

    /**
     * <h2>AOP术语：</h2>
     * <p>
     * <b>织入器通过在切面中定义Pointcut来搜索目标（被代理类）的JoinPoint（切入点），然后把要切入的逻辑（Advice）织入到目标对象里，生成代理类</b>
     * <li>Joinpoint：拦截点，如某个业务方法。所谓连接点是指那些被拦截到的点。在Spring中，这些点指的是方法，因为spring只支持方法类型的连接点，实际上joinpoint还可以是field或类构造器
     * <li>Pointcut：Joinpoint的表达式，表示拦截哪些方法。一个Pointcut对应多个Joinpoint。
     * <li>Advice：要切入的逻辑。所谓的通知是指拦截到joinpoint之后所要做的事情。通知分为前置通知，后置通知，异常通知，最终通知，环绕通知
     * <li>Aspect（切面）：指横切面关注点的抽象即为切面，它与类相似，只是两者的关注点不一样，类是对物体特征的抽象，而切面是横切性关注点的抽象
     * <li>Target（目标对象）：代理的目标对象
     * <li>Weave（织入）：指将Aspect应用到Target对象并且导致proxy对象创建的过程称为织入
     * <li>Introduction（引入）：在不修改类代码的前提下，introduction可以在运行期为类动态的添加一些方法或field
     * <li>AOP代理（AOP Proxy） 在Spring AOP中有两种代理方式，JDK动态代理和CGLIB代理。默认情况下，TargetObject实现了接口时，则采用JDK动态代理；反之，采用CGLIB代理。
     */
    void 术语();

    /**
     * <li>Before Advice：在方法前切入
     * <li>After Advice：在方法后切入，抛出异常则不会切入
     * <li>After Returning Advice：在方法返回后切入，抛出异常则不会切入
     * <li>After Throwing Advice：在方法抛出异常时切入
     * <li>Around Advice：在方法执行前后切入，可以中断或忽略原有流程的执行
     * <p>
     * 通知（Advice）类型
     * <li>@Before 前置通知（Before advice） ：在某连接点（JoinPoint）之前执行的通知，但这个通知不能阻止连接点前的执行。
     * <li>@After 后通知（After advice） ：当某连接点退出的时候执行的通知（不论是正常返回还是异常退出）。
     * <li>@AfterReturning 返回后通知（After return advice） ：在某连接点正常完成后执行的通知，不包括抛出异常的情况。
     * <li>@Around 环绕通知（Around advice） ：包围一个连接点的通知，类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为，也可以选择不执行。
     * <li>@AfterThrowing 抛出异常后通知（After throwing advice） ： 在方法抛出异常退出时执行的通知。
     */
    void advice();

    /**
     * <h2>Spring AOP</h2>是aop实现方案的一种，它支持在运行期基于动态代理的方式将aspect织入目标代码中来实现aop。 但是spring
     * AOP的切入点支持有限，而且对于static方法和final方法都无法支持aop（因为此类方法无法生成代理类）；
     * 另外spring AOP只支持对于ioc容器管理的bean，其他的普通java类无法支持aop。
     * 现在的spring整合了aspectj，在spring体系中可以使用aspectj语法来实现aop。
     */
    void springAOP();
}
